#pragma once
#ifndef Game_Bootstrapper_h
#define Game_Bootstrapper_h

namespace Game {

namespace GameEngine {
class IGameEngine;
}

namespace GraphicsPipeline {
class IGraphicsPipeline;
}

using namespace std;
using namespace GameEngine;
using namespace GraphicsPipeline;

class Bootstrapper {
public:
    Bootstrapper();
    virtual ~Bootstrapper();

    IGameEngine* GetGameEngine() const;
    void SetGameEngine(IGameEngine* val);

    int Run();

    static bool CALLBACK D3D9DeviceAcceptableCallback(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext);
    static HRESULT CALLBACK D3D9DeviceCreatedCallback(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext);
    static void CALLBACK D3D9DeviceDestroyedCallback(void* pUserContext);
    static bool CALLBACK D3D11DeviceAcceptableCallback(const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext);
    static HRESULT CALLBACK D3D11DeviceCreatedCallback(ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext);
    static void CALLBACK D3D11DeviceDestroyedCallback(void* pUserContext);
    static bool CALLBACK DeviceRemovedCallback(void* pUserContext);
    static bool CALLBACK DeviceChangingCallback(DXUTDeviceSettings* pDeviceSettings, void* pUserContext);
private:
    IGameEngine* gameEngine;

    IGraphicsPipeline* graphicsPipeline;

    void DeleteGraphicsPipeline();
    void Finalize();
    void Initialize();

    bool IsD3D9DeviceAcceptable(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed);
    HRESULT D3D9DeviceCreated(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc);
    void D3D9DeviceDestroyed();
    bool IsD3D11DeviceAcceptable(const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, DXGI_FORMAT BackBufferFormat, bool bWindowed);
    HRESULT D3D11DeviceCreated(ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc);
    void D3D11DeviceDestroyed();
    bool OnDeviceRemoved();
    bool OnDeviceChanging(DXUTDeviceSettings* pDeviceSettings);
};

}

#endif
